//*****************************************************************************
// JFab (http://code.google.com/p/jfab)
// Copyright (c) 2011-2012 JFab.org
// Admin jfab@jeffreythompson.net
//
// See the file "LICENSE.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//*****************************************************************************

package org.jfab.core.factory;

import org.jfab.core.model.CGClass;
import org.jfab.core.model.CGConstructor;
import org.jfab.core.model.CGEnum;
import org.jfab.core.model.CGEnumItem;
import org.jfab.core.model.CGField;
import org.jfab.core.model.CGInitializationBlock;
import org.jfab.core.model.CGInterface;
import org.jfab.core.model.CGMethod;
import org.jfab.core.model.CGMethodDeclaration;
import org.jfab.core.model.CGObject;
import org.jfab.core.model.CGParameter;
import org.jfab.core.model.CGProperty;

/**
 * Provides a factory to create model objects.
 */
public class ModelFactory
{
    /** Type name. */
    public static final String CLASS_TYPE = "class";

    /** Type name. */
    public static final String CONSTRUCTOR_TYPE = "constructor";

    /** Type name. */
    public static final String ENUM_ITEM_TYPE = "enumItem";

    /** Type name. */
    public static final String ENUM_TYPE = "enum";

    /** Type name. */
    public static final String FIELD_TYPE = "field";

    /** Type name. */
    public static final String INITIALIZATION_BLOCK_TYPE = "initializationBlock";

    /** Type name. */
    public static final String INTERFACE_TYPE = "interface";

    /** Type name. */
    public static final String METHOD_DECLARATION_TYPE = "methodDeclaration";

    /** Type name. */
    public static final String METHOD_TYPE = "method";

    /** Type name. */
    public static final String PARAMETER_TYPE = "parameter";

    /** Type name. */
    public static final String PROPERTY_TYPE = "property";

    /** New counter. */
    private static int _newClassCount;

    /** New counter. */
    private static int _newConstructorCount;

    /** New counter. */
    private static int _newEnumCount;

    /** New counter. */
    private static int _newEnumItemCount;

    /** New counter. */
    private static int _newFieldCount;

    /** New counter. */
    private static int _newInitializationBlockCount;

    /** New counter. */
    private static int _newInterfaceCount;

    /** New counter. */
    private static int _newMethodCount;

    /** New counter. */
    private static int _newMethodDeclarationCount;

    /** New counter. */
    private static int _newParameterCount;

    /** New counter. */
    private static int _newPropertyCount;

    /**
     * 
     * @param typeName Type name.
     * 
     * @return a new code generator object.
     */
    public CGObject create(final String typeName)
    {
        CGObject answer = null;

        if (CLASS_TYPE.equals(typeName))
        {
            answer = new CGClass();
            answer.setName("Class" + _newClassCount);
        }
        else if (CONSTRUCTOR_TYPE.equals(typeName))
        {
            answer = new CGConstructor();
            answer.setName("Constructor" + _newConstructorCount++);
        }
        else if (ENUM_TYPE.equals(typeName))
        {
            answer = new CGEnum();
            answer.setName("Enum" + _newEnumCount++);
        }
        else if (ENUM_ITEM_TYPE.equals(typeName))
        {
            answer = new CGEnumItem();
            answer.setName("EnumItem" + _newEnumItemCount++);
        }
        else if (FIELD_TYPE.equals(typeName))
        {
            answer = new CGField();
            answer.setName("Field" + _newFieldCount++);
        }
        else if (INITIALIZATION_BLOCK_TYPE.equals(typeName))
        {
            answer = new CGInitializationBlock();
            answer.setName("InitializationBlock"
                    + _newInitializationBlockCount++);
        }
        else if (INTERFACE_TYPE.equals(typeName))
        {
            answer = new CGInterface();
            answer.setName("Interface" + _newInterfaceCount++);
        }
        else if (METHOD_TYPE.equals(typeName))
        {
            answer = new CGMethod();
            answer.setName("Method" + _newMethodCount++);
        }
        else if (METHOD_DECLARATION_TYPE.equals(typeName))
        {
            answer = new CGMethodDeclaration();
            answer.setName("MethodDeclaration" + _newMethodDeclarationCount++);
        }
        else if (PARAMETER_TYPE.equals(typeName))
        {
            answer = new CGParameter();
            answer.setName("Parameter" + _newParameterCount++);
        }
        else if (PROPERTY_TYPE.equals(typeName))
        {
            answer = new CGProperty();
            answer.setName("Property" + _newPropertyCount++);
        }
        else
        {
            System.err.println("ERROR: Unknown type name: " + typeName);
        }

        return answer;
    }
}
